import 'dart:async';
import 'package:audioplayers/audioplayers.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_common_app/api/get_song_url_api.dart';
import 'package:flutter_common_app/data/play_song_data.dart';
import 'package:flutter_common_app/my_app.dart';
import 'package:flutter_common_app/utils/common_util/log_util.dart';
import 'package:flutter_common_app/utils/common_util/shared_preferences/sp_keys_constant.dart';
import 'package:flutter_common_app/utils/common_util/shared_preferences/sp_util.dart';

///音频播放器
class AudioModel extends ChangeNotifier {
  AudioPlayer _audioPlayer;

  AudioPlayerState _playerState;

  AudioPlayerState get playerState => _playerState;

  Duration curSongDuration;

  StreamController<String> _curPositionController =
      StreamController<String>.broadcast();

  Stream<String> get curPositionStream => _curPositionController.stream;

  List<PlaySongData> playList = [];

  PlaySongData currentSongData;

  bool audioBottomWidgetStatus = false;

  int _currentIndex = 0;

  void init() {
    LogUtil.v('初始化AudioModel');
    AudioPlayer.logEnabled = false;
    _audioPlayer = AudioPlayer();
    _audioPlayer.setReleaseMode(ReleaseMode.STOP);
    _audioPlayer.onPlayerStateChanged.listen((event) {
      _playerState = event;
      if (event == AudioPlayerState.COMPLETED && playList.length > 1) {
        nextPlay();
      }
      notifyListeners();
    });
    _audioPlayer.onDurationChanged.listen((event) {
      curSongDuration = event;
    });
    _audioPlayer.onAudioPositionChanged.listen((event) {
      sinkProgress(event.inMilliseconds > curSongDuration.inMilliseconds
          ? curSongDuration.inMilliseconds
          : event.inMilliseconds);
    });
  }

  void setAudioBottomWidgetStatus(bool hide) {
    audioBottomWidgetStatus = hide;
    notifyListeners();
  }

  void initSongsData() async {
    playList = PlaySongData.fromJsonList(
        SpUtil.getObjectList(SpKeysConstant.playList));
    Map songJson = SpUtil.getObject(SpKeysConstant.currentSong);
    if (playList.length > 0) {
      audioBottomWidgetStatus = true;
      currentSongData = playList[_currentIndex];
    }
    if (songJson != null) {
      currentSongData = PlaySongData.fromJson(songJson);
      _currentIndex = playList.indexOf(currentSongData);
    }
    LogUtil.v('initPlayList->:$playList');
    LogUtil.v('currentSongData$currentSongData');
  }

  void deleteSong(PlaySongData playSongData) {
    playList.remove(playSongData);
    LogUtil.v('删除音乐$playSongData');
    _savePlayList();
    notifyListeners();
  }

  void playAll(List<PlaySongData> list) {
    playList = [];
    playList.addAll(list);
    _currentIndex = 0;
    _play(list[_currentIndex]);
  }

  void nextPlay() {
    LogUtil.v('下一曲');
    if (_currentIndex != playList.length - 1) {
      _currentIndex++;
    } else {
      _currentIndex = 0;
    }
    _play(playList[_currentIndex]);
  }

  void lastPlay() {
    LogUtil.v('上一曲');
    if (_currentIndex > 0) {
      _currentIndex--;
    } else {
      _currentIndex = playList.length - 1;
    }
    _play(playList[_currentIndex]);
  }

  void playOneSong(PlaySongData playSongData) {
    //传入的playSongData 为新建类，所以这里要对比，否则影想_play方法内
    for (var i = 0; i < playList.length; i++) {
      if (playList[i].id == playSongData.id) {
        playSongData = playList[i];
      }
    }
    _play(playSongData);
  }

  //歌曲进度
  void sinkProgress(int m) {
    _curPositionController.sink.add('$m-${curSongDuration.inMilliseconds}');
  }

  //播放/暂停
  void togglePlay() {
    LogUtil.v(_playerState);
    if (_playerState == null) {
      _play(currentSongData);
      return;
    }
    if (_playerState == AudioPlayerState.PLAYING) {
      _audioPlayer.pause();
    } else {
      _audioPlayer.resume();
    }
  }

  void pausePlay(){
    _audioPlayer.pause();
  }

  /// 跳转到固定时间
  void seekPlay(int milliseconds){
    _audioPlayer.seek(Duration(milliseconds: milliseconds));
    _audioPlayer.resume();
  }

  void _play(PlaySongData playSongData) {
    if (!playList.contains(playSongData)) {
      playList.add(playSongData);
    }
    _currentIndex = playList.indexOf(playSongData);
    currentSongData = playSongData;
    _playUrl(playSongData);
    _savePlayList();
    _saveCurrentSong();
    notifyListeners();
  }

  void _savePlayList() {
    SpUtil.putObjectList(SpKeysConstant.playList, playList);
  }

  void _saveCurrentSong() {
    SpUtil.putObject(SpKeysConstant.currentSong, currentSongData);
  }

  void _playUrl(PlaySongData playSongData) async {
    String url = await _getSongUrlApi(playSongData.id);
    if (url.isEmpty || url == null) {
      return;
    }
    _audioPlayer.play(
      url,
      stayAwake: true,
      isLocal: false,
    );
  }

  Future<String> _getSongUrlApi(int id) async {
    BuildContext context = navigatorKey.currentState.context;
    GetSongUrlApi getSongUrlApi = GetSongUrlApi(context);
    getSongUrlApi.getParams()['id'] = id;
    Response response = await getSongUrlApi.send();
    return response.data['data'][0]["url"];
  }

  @override
  void dispose() {
    super.dispose();
    _audioPlayer.dispose();
    _curPositionController.close();
  }
}
